#include <iostream>

#include <string>
#include <unordered_map>
#include <set>
#include <vector>
#include <sw/redis++/redis++.h>
#include <chrono>
#include <thread>

#include "util.hpp"

using std::cout;
using std::cin;
using std::string;
using std::endl;
using std::unordered_map;
using std::vector;
using std::set;

using sw::redis::Redis;
using sw::redis::StringView;

using namespace std::chrono_literals;


void Zadd(Redis& redis) {
    redis.flushdb();

    // 第一种
    redis.zadd("key", "语文", 94);
    // 第二种，一次添加多个
    redis.zadd("key", {
        std::make_pair("数学", 120),
        std::make_pair("英语", 120)
    });
    // 第三种，基于容器
    vector<std::pair<string, double>> input = {
        std::make_pair("化学", 100),
        std::make_pair("地理", 40)
    };
    redis.zadd("key", input.begin(), input.end());

    // 获取范围内的元素
    // zrange 支持两种风格
    // 1. 只查询 member, 不要 score
    // 2. 只查询 mmeber，还要 score
    //      如果容器是 string, 那么就是第一种情况
    //      如果容器是 pair<string, double>, 那么就是第二种情况
    vector<string> members;
    auto it = std::back_inserter(members);
    redis.zrange("key", 0, -1, it);
    Print(members);

    vector<std::pair<string, double>> members_with;
    auto it2 = std::back_inserter(members_with);
    redis.zrange("key", 0, -1, it2);
    PrintPair(members_with);
}


void Zcard(Redis& redis) {
    redis.flushdb();
    redis.zadd("key", {
        std::make_pair("数学", 120),
        std::make_pair("英语", 120),
        std::make_pair("政治", 96)
    });

    long long size = redis.zcard("key");
    cout << "个数 = " << size << endl;

    // 删除元素
    redis.zrem("key", "数学");
}

void Zscore(Redis& redis) {
    redis.flushdb();
    redis.zadd("key", {
        std::make_pair("数学", 120),
        std::make_pair("英语", 120),
        std::make_pair("政治", 96)
    });

    // zscore 返回的是 OptionalDouble
    auto score = redis.zscore("key", "数学");
    cout << "数学分数 = " << score.value() << endl;

    // 获取该 member 的排名
    auto rank = redis.zrank("key", "英语");
    if (rank) {
        cout << "rand = " << rank.value() << endl;
    }
}

int main()
{
    Redis redis("tcp://127.0.0.1:6379");
    Zadd(redis);

    Zcard(redis);

    Zscore(redis);

    return 0;
}